home *** CD-ROM | disk | FTP | other *** search
/ World of Amiga / World of Amiga.iso / archive / assembly / lsd-lo.s.lha / MultiDiskTrackLoader.Src < prev    next >
Text File  |  1980-01-18  |  12KB  |  599 lines

  1.  
  2. * EXAMPLE OF USE!
  3.  
  4.     move.w #$4000,$dff09a    ;Disable Irqs....
  5.  
  6.     jsr INIT_DISK
  7.  
  8. go    moveq  #1,d5        ;Load from disk named '1'
  9.     move.l #$10000,d6        ;Bytes to load
  10.     move.w #880,d7        ;Start block
  11.     move.l #loadspace,a6    ;Address of load
  12.  
  13.     jsr BLOCK_LOAD
  14.  
  15.     tst.w d7            ;check for failure
  16.     beq.s end
  17.  
  18.     move.w #$7fff,d0        ;red screen = error
  19. erlp    move.w #$f00,$dff180
  20.     dbf d0,erlp
  21.  
  22. end    jsr MOTOR_OFF
  23.     move.w #$c000,$dff09a
  24.     rts
  25.  
  26. loadspace dcb.l $8000,$00
  27.  
  28. *****************************************************************************
  29.  
  30.      *     System Independant Multi-Disk Block Loader V1.1 - 26/4/94   *
  31.      *-----------------------------------------------------------------*
  32.  
  33.                     * By PHIL RUSTON AKA:PHIL!94/LSD *
  34.  
  35. * You MUST call "INIT_DISK" before loading for the 1st ever time.
  36.  
  37. * To LOAD A FILE Set:-
  38.  
  39. * A6 - Destination Address.
  40. * D5 - Disk / Drive Number to load from. (see below).
  41. * D6 - Bytes to load.
  42. * D7 - Starting Block.
  43.  
  44. * Then call: "BLOCK_LOAD" - All registers preserved except D7
  45.  
  46. * D7 returns as 00 is load OK. Else one of the following errors:
  47.  
  48. * 01 = No speed signal from motor   (disk ejected whilst loading)
  49. * 02 = No DMA transfer time out     (no sync / ''            '' )
  50. * 03 = Disk removed from drive      (whilst loading)
  51. * 04 = Can't find that disk block   (disk corrupt)
  52. * 05 = Wrong track marker ID        ('')
  53. * 06 = Checksum error on disk block ('')
  54. * 07 = Block number req'd too big   (you've (in)directly asked for >$6df)
  55. * 08 = Disk requester               (Disk specifified in D5 isnt inserted)
  56. * 09 = No disk in that drive        (Direct drive access failed)
  57. * 0A = That drive is not connected  (''                      '')
  58.  
  59. * When setting D5, if you want to look for a 'named' disk (see docs on
  60. * naming disks) then just set the Longword as $0-$7f as normal in D5. 
  61. * If you  want to directly access a DRIVE (df0-df3) set the drive number
  62. * to access in D5 and SET the HIGH word to $FFFF. See docs for more info.
  63.  
  64. * Call "MOTOR_OFF" when finished loading for a while!!
  65.  
  66. *******************************************************************************
  67.  
  68.     section loadcode,code
  69.  
  70. **************
  71. * Initialize *
  72. **************
  73.  
  74. INIT_DISK    movem.l a0-a6/d0-d7,-(a7)
  75.     move.l #$dff000,a0
  76.     move.l #$bfd000,a1        
  77.     move.l #Variables,a2
  78.     clr.l attempts(a2)
  79.     clr.l tracksides(a2)
  80.     clr.l track_in(a2)
  81.     moveq #-1,d7
  82.     move.l d7,disks_in(a2)
  83.     move.b d7,track_in(a2)
  84.     bsr motor_off
  85.  
  86.     bset #3,drives_avail(a2)    ;df0: assumed always available
  87.     moveq #4,d1
  88.  
  89. ID_drives    move.b #$7f,$100(a1)    ;what externals are connected?
  90.     bclr d1,$100(a1)        
  91.     move.w #100,d7
  92.     bsr cia_wait
  93.     move.b #$ff,$100(a1)        
  94.     bclr d1,$100(a1)
  95.     moveq #$1f,d7
  96.     moveq #0,d0
  97. df1idloop    lsl.l #1,d0
  98.     bclr d1,$100(a1)
  99.     btst #5,$1001(a1)
  100.     beq.s nxtbit
  101.     ori.w #1,d0
  102. nxtbit    bset d1,$100(a1)
  103.     dbf d7,df1idloop
  104.     not.l d0
  105.  
  106.     cmpi.l #-1,d0        
  107.     bne.s no_drive        
  108.     bset d1,drives_avail(a2)
  109.  
  110. no_drive    addq.w #1,d1
  111.     cmpi.w #7,d1
  112.     bne.s ID_drives
  113.     bsr motor_off
  114.  
  115.     moveq #0,d0        ;now identify any disks present.
  116.     moveq #3,d1        
  117. id_dsk_lp    btst d1,drives_avail(a2)
  118.     beq.s no_drv
  119.  
  120.     move.b d0,use_drive(a2)
  121.     move.b #$ff,$100(a1)
  122.     bclr d1,$100(a1)
  123.     bsr stepin
  124.     bsr initialize_drive
  125.     btst #2,$1001(a1)
  126.     beq.s no_drv
  127.     move.b #1,start_motor(a2)
  128.     bsr identify_disk
  129.  
  130. no_drv    bsr motor_off
  131.     addq.w #1,d1
  132.     addq.w #1,d0
  133.     cmpi.w #4,d0
  134.     bne.s id_dsk_lp
  135.     movem.l (a7)+,a0-a6/d0-d7
  136.     rts
  137.  
  138. ******************
  139. * Construct file *
  140. ******************
  141.  
  142. BLOCK_LOAD
  143.  
  144.     movem.l d0-d6/a0-a6,-(a7)
  145.     move.l #$dff000,a0
  146.     move.l #$bfd000,a1
  147.     move.l #Variables,a2
  148.     clr.b error(a2)
  149.     clr.b start_motor(a2)
  150.     move.l d7,d4
  151.     subq.l #1,d6
  152.     
  153.     tst.l d5            ;Disk or Drive access?
  154.     bpl.s find_disk
  155.  
  156. *****************************************************************************
  157.  
  158.     moveq #3,d7        ;Direct drive access but is that
  159.     add.w d5,d7        ;drive attatched?
  160.     btst d7,drives_avail(a2)
  161.     bne.s drive_ok
  162.     move.b #$a,error(a2)    ;Drive not connected - error $a
  163.     bra load_done
  164. drive_ok    
  165.     cmp.b use_drive(a2),d5    ;same drive as before?
  166.     beq loader
  167.     bsr motor_off
  168.     move.b d5,use_drive(a2)
  169.     moveq #3,d0
  170.     add.w d5,d0
  171.     bclr d0,$100(a1)
  172.     move.b #1,start_motor(a2)
  173.     bsr wait1msec
  174.     btst #2,$1001(a1)
  175.     bne.s disk_now
  176.     bsr stepcheck
  177.     btst #2,$1001(a1)
  178.     bne.s disk_now2
  179.     move.b #$9,error(a2)
  180.     bra load_done
  181.  
  182. disk_now2    bsr initialize_drive
  183.     bsr identify_disk        
  184. disk_now    bra loader
  185.  
  186. *****************************************************************************
  187.  
  188. find_disk    moveq #0,d0        ;Name disk access - is the required
  189. fdisk_lp    cmp.b disks_in(a2,d0.w),d5    ;disk already in a drive?
  190.     beq found_disk
  191.     addq.w #1,d0
  192.     cmpi.w #4,d0
  193.     bne.s fdisk_lp
  194.                 
  195. disk_gone    bsr motor_off        ;no drive contains req'd disk
  196.     moveq #0,d0        ;so switch 'em off and see if
  197.     moveq #3,d1        ;any drive has had a disk replaced.
  198. fdisk_lp2    btst d1,drives_avail(a2)
  199.     beq.s dsk_n_rem
  200.     move.b #$ff,$100(a1)
  201.     bclr d1,$100(a1)
  202.     bsr wait1msec
  203.     btst #2,$1001(a1)        ;disk replaced / ejected?
  204.     bne.s dsk_n_rem
  205.     move.b d0,use_drive(a2)
  206.     bsr stepcheck
  207.     btst #2,$1001(a1)
  208.     beq.s dsk_n_rem
  209.     move.b #1,start_motor(a2)
  210.     bsr initialize_drive
  211.     bsr identify_disk        ;here's a new disk to identify
  212.     cmp.b disks_in(a2,d0.w),d5
  213.     beq.s loader
  214.     bsr motor_off
  215.  
  216. dsk_n_rem    addq.w #1,d1
  217.     addq.w #1,d0
  218.     cmpi.w #4,d0
  219.     bne.s fdisk_lp2
  220.     bsr motor_off
  221.     move.b #$08,error(a2)    ;disk request - error 8.
  222.     bra load_done
  223.  
  224. found_disk
  225.     
  226.     cmp.b use_drive(a2),d0    ;is this a load from the same
  227.     beq loader        ;drive as the last load?
  228.     bsr motor_off
  229.     move.b d0,use_drive(a2)
  230.     bclr d1,$100(a1)
  231.     move.b #1,start_motor(a2)
  232.     bsr wait1msec    
  233. same_drv    btst #2,$1001(a1)        ;this drive had the required disk
  234.     bne loader        ;but has it been ejected?
  235.     move.b #$ff,disks_in(a2,d0.w)
  236.     bra disk_gone        ;yep - so look else where
  237.     
  238. Loader    move.l d4,d0
  239. Nxt_block    bsr get_block
  240.     tst.b error(a2)
  241.     bne.s Load_done
  242.     tst.l d6            ;Byte countdown ended?
  243.     bmi.s load_done
  244.     addq.w #1,d0
  245.     bra.s Nxt_block
  246.  
  247. load_done    move.b #$ff,track_in(a2)
  248.     tst.b error(a2)
  249.     beq.s no_error
  250.     bsr motor_off
  251.     move.w #1000,d7
  252.     bsr cia_wait
  253. no_error    moveq #0,d7
  254.     move.b error(a2),d7
  255.     movem.l (a7)+,d0-d6/a0-a6
  256.     rts
  257.  
  258. *************
  259. * Shut down *
  260. *************
  261.  
  262. MOTOR_OFF    movem.l a1/a2/d7,-(a7)
  263.     move.l #$bfd000,a1
  264.     move.l #Variables,a2
  265.     move.b #$ff,$100(a1)
  266.     move.b #$87,$100(a1)
  267.     bsr wait1msec
  268.     move.b #$ff,$100(a1)
  269.     move.b #$ff,use_drive(a2)
  270.     moveq #100,d7
  271.     bsr cia_wait
  272.     movem.l (a7)+,a1/a2/d7
  273.     rts
  274.  
  275. *****************************************************************************
  276.  
  277. *************
  278. * Get Block *
  279. *************
  280.  
  281. * D0 will equal block number required ($0 - $6df)
  282.  
  283. Get_block    cmp.w #$6df,d0        ;check block is range
  284.     bls.s blockinrange
  285.     move.b #$7,error(a2)
  286.     bra No_reload
  287.  
  288. Blockinrange
  289.  
  290.     move.w #$0503,attempts(a2)
  291.     move.l d0,d1        
  292.     divu #11,d1        ;what track/side is that on?
  293.     cmp.b track_in(a2),d1    
  294.     beq.s Trksde_in        ;no need to load!
  295.     
  296. Reload    bsr Fetch_trackside        ;loads MFM track required
  297.     tst.b error(a2)
  298.     bne No_reload
  299.  
  300. Trksde_in    clr.b error(a2)        ;find a sector
  301.     swap d1            ;get sector number lo.
  302.     move.l #MFMbuffer,a3
  303.     lea $31fe(a3),a5
  304. find_sync    move.w #$4489,d7
  305. fs_loop    cmp.w (a3)+,d7
  306.     beq.s found_sync
  307.     cmp.l a5,a3
  308.     bls.s fs_loop
  309.     move.b #4,error(a2)        ;couldnt find that sector-error 4
  310.     bra MFM_error
  311.  
  312. found_sync    
  313.  
  314.     cmp.w (a3),d7        ;2 syncs?
  315.     beq.s syncstart
  316.     subq.w #2,a3
  317.  
  318. syncstart    lea $2a(a3),a4        ;Check header checksum.
  319.     bsr decode_lw        
  320.     move.l $2(a3),d3
  321.     move.l $6(a3),d4
  322.     andi.l #$55555555,d3
  323.     andi.l #$55555555,d4
  324.     eor.l d4,d3
  325.     cmp.l d3,d5
  326.     bne.s Not_sector
  327.  
  328.     lea $2(a3),a4        ;Track mark = Head position?
  329.     bsr decode_lw
  330.     move.l d5,d4        
  331.     swap d4
  332.     moveq #0,d7
  333.     move.b use_drive(a2),d7
  334.     cmp.b tracksides(a2,d7.w),d4
  335.     beq.s Track_mark_ok
  336.     move.b #5,error(a2)        ;wrong track mark - error 5
  337.     bra MFM_error
  338.  
  339. Track_mark_ok
  340.  
  341.     lsr.w #8,d5        ;Is this the sector required?
  342.     cmp.b d5,d1
  343.     beq.s Found_block
  344.     
  345. Not_sector
  346.  
  347.     add.w #$430,a3          ;loop until find correct sector
  348.     bra.s find_sync
  349.  
  350. Found_Block
  351.     
  352.     moveq #0,d2        ;Transfer converted MFM to dest.
  353.     move.l #$55555555,d7
  354.     lea $3a(a3),a4        
  355.     lea $23a(a3),a5
  356.     move.l d6,d1        ;back up pointers in case of error.
  357.     move.l a6,a3        
  358.     moveq #$7f,d3
  359.  
  360. Conv_lw    move.l (a4)+,d5
  361.     move.l (a5)+,d4
  362.     and.l d7,d5
  363.     and.l d7,d4
  364.     eor.l d5,d2        ;update checksum
  365.     eor.l d4,d2
  366.     add.l d5,d5
  367.     or.l d4,d5
  368.     subq.l #4,d6
  369.     bmi.s lst_bytes
  370.     move.l d5,(a6)+
  371. nxt_lw    dbf d3,Conv_lw
  372.     bra.s blk_done
  373.  
  374. Lst_bytes    move.w d6,d4
  375.     addq.w #4,d4        ;last bytes
  376.     bmi.s nxt_lw
  377.  
  378. Lb_loop    rol.l #8,d5
  379.     move.b d5,(a6)+
  380.     dbf d4,Lb_loop
  381.     bra.s nxt_lw
  382.         
  383. blk_done    sub.w #$208,a4        ;get data checksum
  384.     bsr decode_lw        
  385.     cmp.l d5,d2
  386.     beq.s no_reload
  387.     move.b #6,error(a2)        ;checksum error - error 6
  388.     move.l a3,a6        ;restore pointers
  389.     move.l d1,d6
  390.  
  391. MFM_error    move.l d0,d1        
  392.     divu #11,d1        
  393.     subq.b #1,attempts(a2)
  394.     bne Reload
  395.     bsr initialize_Drive    ;reset heads
  396.     move.b #5,attempts(a2)
  397.     subq.b #1,attempts+1(a2)
  398.     bne Reload
  399.  
  400. No_reload    rts
  401.  
  402. *****************************************************************************
  403.  
  404. * MFM Track loader!
  405. * D1 will equal trackside 0 - 159
  406.  
  407. Fetch_trackside
  408.     
  409.         
  410.     clr.b error(a2)        
  411.     tst.b start_motor(a2)    ;motor on already?
  412.     beq.s motor_ok
  413.  
  414.     clr.b start_motor(a2)
  415.     move.b #$7f,$100(a1)
  416.     moveq #3,d7
  417.     add.b use_drive(a2),d7
  418.     bclr d7,$100(a1)
  419.     move.w #200,d2        ;wait for correct motor speed.
  420. wdskrdy    moveq #10,d7
  421.     bsr cia_wait        
  422.     btst #5,$1001(a1)        
  423.     dbeq d2,wdskrdy
  424.     tst.w d2
  425.     bpl.s motor_ok
  426.     move.b #1,error(a2)        ;no speed signal - error 1
  427.     btst #2,$1001(a1)                
  428.     bne.s disk_ok
  429.     move.b #3,error(a2)        ;disk removed - error 3
  430. disk_ok    bra trackload_end
  431.  
  432. motor_ok    move.w d1,d3
  433.     lsr.b #1,d3        ;select disk side to load from.
  434.     bcc.s head1
  435.     bclr #2,$100(a1)
  436.     bra.s checkhead
  437. head1    bset #2,$100(a1)
  438.  
  439. checkhead    moveq #0,d7
  440.     move.b use_drive(a2),d7
  441.     move.b tracksides(a2,d7.w),d2    ;ensure head is over correct
  442.     lsr.b #1,d2        ;track
  443.     cmp.b d2,d3
  444.     beq.s headok
  445.     bls.s seekout
  446.     bsr stepin
  447.     bra.s checkhead 
  448. seekout    bsr stepout    
  449.     bra.s checkhead
  450.  
  451. headok    moveq #0,d7
  452.     move.b use_drive(a2),d7
  453.     move.b d1,tracksides(a2,d7.w)
  454.     move.w #$2,$9c(a0)        ;clear disk block irq
  455.     moveq #18,d7        ;settle wait.
  456.     bsr cia_wait
  457.  
  458.     move.l #mfmbuffer,$20(a0)
  459.     move.w #$4000,$24(a0)    
  460.     move.w #$8010,$96(a0)    ;enable dma
  461.     move.w #$6800,$9e(a0)    
  462.     move.w #$9500,$9e(a0)
  463.     move.w #$4489,$7e(a0)    ;sync
  464.     move.w #$9900,$24(a0)    
  465.     move.w #$9900,$24(a0)    
  466.  
  467.     move.w #200,d2
  468. waitdirq    moveq #10,d7
  469.     bsr cia_wait        
  470.     btst #1,$1f(a0)        
  471.     dbne d2,waitdirq
  472.     tst.w d2
  473.     bpl.s read_ok
  474.     move.b #2,error(a2)        ;No DMA finish-Time Out-error 2
  475.  
  476. read_ok    move.b d1,track_in(a2)
  477.     move.w #$4000,$24(a0)    
  478.     move.w #$10,$96(a0)        ;disable dma
  479.  
  480. Trackload_end
  481.  
  482.     rts
  483.  
  484. *******************************************************************************
  485.  
  486. decode_lw    move.l #$55555555,d7    ;decode two consec mfm longwords
  487.     move.l (a4),d5        ;into d5
  488.     move.l $4(a4),d4    
  489.     and.l d7,d5    
  490.     and.l d7,d4
  491.     add.l d5,d5
  492.     or.l d4,d5        
  493.     rts
  494.  
  495. stepout    moveq #0,d7
  496.     move.b use_drive(a2),d7
  497.     subq.b #2,tracksides(a2,d7.w)
  498.     bset #1,$100(a1)
  499.     bra.s step
  500.  
  501. stepin    moveq #0,d7
  502.     move.b use_drive(a2),d7
  503.     addq.b #2,tracksides(a2,d7.w)
  504.     bclr #1,$100(a1)
  505. step    bsr.s shortwait
  506.     bclr #0,$100(a1)
  507.     bsr.s shortwait
  508.     bset #0,$100(a1)
  509.     moveq #4,d7
  510.     bsr cia_wait
  511.     rts
  512.  
  513. shortwait    nop
  514.     nop
  515.     nop    
  516.     nop    
  517.     rts
  518.  
  519. initialize_drive
  520.  
  521.     btst #$4,$1001(a1)        
  522.     beq.s gottrack0
  523.     bsr.s stepout
  524.     bra.s initialize_drive
  525.  
  526. gottrack0    moveq #0,d7
  527.     move.b use_drive(a2),d7
  528.     clr.b tracksides(a2,d7.w)
  529.     move.w #20,d7
  530.     bsr cia_wait
  531.     rts
  532.  
  533. Identify_disk
  534.  
  535.     movem.l a6/d0-d1/d4-d7,-(a7)
  536.     move.l #ID_buffer,a6
  537.     moveq #$c,d6
  538.     moveq #$0,d0
  539.     bsr get_block
  540.     moveq #0,d6
  541.     move.b use_drive(a2),d6
  542.     tst.b error(a2)
  543.     bne.s not_sys
  544.  
  545.     move.w ID_buffer+8,d7
  546.     cmpi.w #"PR",d7
  547.     beq.s sys_disk
  548. not_sys    moveq #-1,d7
  549.     bra.s what_disk
  550.  
  551. sys_disk    move.w ID_buffer+$a,d7
  552. what_disk    move.b d7,disks_in(a2,d6.w)
  553.     move.b #$ff,track_in(a2)
  554.     movem.l (a7)+,a6/d0-d1/d4-d7
  555.     rts
  556.  
  557. stepcheck    moveq #0,d7
  558.     move.b use_drive(a2),d7
  559.     btst #1,tracksides(a2,d7.w)
  560.     bne.s h_odd
  561.     bsr stepin
  562.     bra.s stepdone
  563. h_odd    bsr stepout
  564. stepdone    rts
  565.  
  566. wait1msec moveq #1,d7
  567.  
  568. cia_wait    move.b #$08,$f00(a1)    ;set one shot / stop timer.
  569.     move.b #$cc,$600(a1)    ;set timer lo
  570.     move.b #$02,$700(a1)    ;set timer hi (starts counter)
  571. ciawlp2    btst #0,$f00(a1)        ;wait for ciab timer b to timeout
  572.     bne.s ciawlp2
  573.     subq.w #1,d7
  574.     bne.s cia_wait        ;d7 = milliseconds to wait.
  575.     rts
  576.  
  577. *******************************************************************************
  578.  
  579. Attempts     equ $0
  580. Error           equ $2
  581. Start_motor  equ $3
  582. Disks_in     equ $4
  583. Tracksides   equ $8
  584. Track_in     equ $c
  585. Drives_avail equ $d
  586. Use_drive    equ $e
  587.  
  588. variables    dcb.l 4,$0
  589.  
  590. ID_buffer dcb.l 3,$0
  591.  
  592.     section chipstuff,data_c
  593.  
  594. MFMbuffer    dcb.w $1910,$0000
  595.  
  596. *******************************************************************************
  597.  
  598.  
  599.